<?php

namespace TuxDrink\TuxDb\Mysql\Drink;

use TuxDrink\TuxDb\Mysql\Drink\Model\GlobalImageTable;
use TuxDrink\TuxDb\Mysql\Drink\Model\GlobalImageLinkPendingTable;
use TuxDrink\TuxDb\Mysql\Drink\Model\GlassTypeTable;
use TuxDrink\TuxDb\Mysql\TuxDbMysqlAbstract;
use TuxDrink\TuxDb\TuxImageInterface;
use TuxCocktail\TuxDb\Mysql\Cocktail\Model\SurveAttrTypeTable;
use Zend\Validator\Explode;
use Zend\Db\Sql\Expression;
use TuxDrink\TuxDb\Mysql\Drink\Model\ShakerTypeTable;
use TuxDrink\TuxDb\Mysql\Drink\Model\GlobalImageLinkTable;
use Zend\Db\Adapter\Adapter;
use TuxDrink\TuxDb\Drink\Util\TuxS3Util;

class TuxDbMysqlImage extends TuxDbMysqlAbstract implements TuxImageInterface {
	
	protected $supportedImageMimeTypes = array('image/gif','image/jpeg','image/png','image/bmp','image/tiff');


    private $imagesDirectory=null;

    public function setImagesDirectory($dir) {
        $this->imagesDirectory=$dir;
    }

	/**
	 *
	 * @var TuxS3Util
	 */
	private $tuxS3Util;
	
	private $config;
	
	/**
	 * 
	 *
	 * @param TuxS3Util $s3
	 */
	public function __construct($config,$s3) {
		parent::__construct($config);
		$this->tuxS3Util=$s3;
		$this->config=$config;
	}
	
	
	
	/**
	 * 
	 * @var GlobalImageLinkPendingTable
	 */
	private $globalImageLinkPendingTable;
	
	/**
	 * 
	 * @var GlobalImageTable
	 */
	private $globalImageTable;
	
	/**
	 * 
	 * @var GlassTypeTable
	 */
	private $glassTypeTable;
	
	/**
	 * 
	 * @var \TuxDrink\TuxDb\Mysql\Drink\Model\SurveAttrTypeTable
	 */
	private $surveAttrTypeTable;
	
	/**
	 * 
	 * @var ShakerTypeTable
	 */
	private $shakerTypeTable;
	
	/**
	 * 
	 * @var GlobalImageLinkTable
	 */
	private $globalImageLinkTable;
	
	/**
	 * 
	 * @return \TuxDrink\TuxDb\Mysql\Drink\Model\GlobalImageLinkTable
	 */
	private function getGlobalImageLinkTable() {
		if (!$this->globalImageLinkTable) {
			$this->globalImageLinkTable = new GlobalImageLinkTable($this->tuxDb->getInstance());
		}
		return $this->globalImageLinkTable;
	}
	
	/**
	 * 
	 * @return \TuxDrink\TuxDb\Mysql\Drink\Model\ShakerTypeTable
	 */
	private function getShakerTypeTable() {
		if (!$this->shakerTypeTable) {
			$this->shakerTypeTable =  new ShakerTypeTable($this->tuxDb->getInstance());
		}
		return $this->shakerTypeTable;
	}
	
	/**
	 * 
	 * @return \TuxCocktail\TuxDb\Mysql\Cocktail\Model\SurveAttrTypeTable
	 */
	private function getSurveAttrTypeTable() {
		if (!$this->surveAttrTypeTable) {
			$this->surveAttrTypeTable = new SurveAttrTypeTable($this->tuxDb->getInstance());
		}
		return $this->surveAttrTypeTable;
	}
	
	/**
	 * 
	 * @return \TuxDrink\TuxDb\Mysql\Drink\Model\GlassTypeTable
	 */
	private function getGlassTypeTable() {
		if (!$this->glassTypeTable) {
			$this->glassTypeTable = new GlassTypeTable($this->tuxDb->getInstance());
		}
		return $this->glassTypeTable;
	}
	
	/**
	 * 
	 * @return \TuxDrink\TuxDb\Mysql\Drink\Model\GlobalImageLinkPendingTable
	 */
	private function getGlobalImageLinkPendingTable() {
		if (!$this->globalImageLinkPendingTable) {
			$this->globalImageLinkPendingTable = new GlobalImageLinkPendingTable($this->tuxDb->getInstance());
		}
		return $this->globalImageLinkPendingTable;
	}
	
	/**
	 * 
	 * @return \TuxDrink\TuxDb\Mysql\Drink\Model\GlobalImageTable
	 */
	private function getGlobalImageTable() {
		if (!$this->globalImageTable) {
			$this->globalImageTable = new GlobalImageTable($this->tuxDb->getInstance());
		}
		return $this->globalImageTable;
	}
	
	public function markPendingImage($globalImageId, $typeId, $primaryKey) {
		$pendingImageLinkData = array (
		
				'global_image_link_pending_imageid'=>$globalImageId,
				'global_image_link_pending_typeid'=>$typeId,
				'global_image_link_pending_pkey'=>$primaryKey,
		
		);
		$this->getGlobalImageLinkPendingTable()->insert($pendingImageLinkData);
		
	}
	
	public function rotateGlobalImageS3($id, $degrees) {
		$fullId=sprintf('%010d',$id);
		$thumbImage = 'my-images/' . 'thumb_'.$fullId.'.png';
		$fullImage = 'my-images/' . 'image_'.$fullId.'.png';
		$this->tuxS3Util->setBucket('myalcoholist-tuxin-com');
		$thumImageData=$this->tuxS3Util->download($thumbImage);
		$fullImageData=$this->tuxS3Util->download($fullImage);
		/**
			@var \Imagick
		 */
		$im = new \Imagick();
		$im->readimageblob($thumImageData);
		$im->rotateimage(new \ImagickPixel('#00000000'), $degrees);
		$thumImageData=$im->getimageblob();
		$im->clear();
		$im->readimageblob($fullImageData);
		$im->rotateimage(new \ImagickPixel('#00000000'), $degrees);
		$fullImageData=$im->getimageblob();
		
		$this->tuxS3Util->uploadPng($thumbImage, $thumImageData);
		$this->tuxS3Util->uploadPng($fullImage, $fullImageData);		

	}
	
	public function rotateGlobalImage($id,$degrees) {
		$fullId=sprintf('%010d',$id);
		$thumbImage = $this->imagesDirectory . 'thumb_'.$fullId.'.png';
		$fullImage = $this->imagesDirectory . 'image_'.$fullId.'.png';
		if (!is_file($thumbImage)) {
			throw new \Exception("thumb file not found");
		}
		if (!is_file($fullImage)) {
			throw new \Exception("image file not found");
		}
		$im = new \Imagick();
		$im->readimage($thumbImage);
		$im->rotateimage(new \ImagickPixel('#00000000'), $degrees);
		$im->writeimage($thumbImage);
		$im->clear();
		$im->readimage($fullImage);
		$im->rotateimage(new \ImagickPixel('#00000000'), $degrees);
		$im->writeimage($fullImage);
	
	}
	
	public function updateCocktailImageId($cocktailId,$imageId) {
		$globalImageLinkTable = $this->getGlobalImageLinkTable();
		$globalImageLinkTable->delete(array('global_image_type_id'=>2,'table_pkey'=>$cocktailId));
		$globalImageLinkTable->addGlobalImageLink($imageId, 2, $cocktailId);
	}
	
	public function confirmPendingImage($id) {
		$globalImageLinkPendingTable = $this->getGlobalImageLinkPendingTable();
		$queryString = "insert into global_image_link(global_image_id,global_image_type_id,table_pkey) ".
				"select global_image_link_pending_imageid,global_image_link_pending_typeid,global_image_link_pending_pkey ".
				"from global_image_link_pending ".
				"where global_image_link_pending_id = ".$globalImageLinkPendingTable->getAdapter()->getPlatform()->quoteValue($id);
		$globalImageLinkPendingTable->getAdapter()->query($queryString,Adapter::QUERY_MODE_EXECUTE);
		$globalImageLinkPendingTable->delete(array('global_image_link_pending_id'=>$id));
	
	}
	
	public function deletePendingImage($id) {
		$globalImageLinkPendingTable = $this->getGlobalImageLinkPendingTable();
		$globalImageLinkPendingTable->delete(array('global_image_link_pending_id'=>$id));
		//TODO: delete the actual image?
	}
	
	
	public function deleteImageS3($imageId) {
		$this->getGlobalImageTable()->deleteGlobalImage($imageId);
		$this->getGlobalImageLinkPendingTable()->delete(array('global_image_link_pending_imageid'=>$imageId));
		$this->getGlobalImageLinkTable()->delete(array('global_image_id'=>$imageId));
		$imgAppend=sprintf('%010u',$imageId).'.png';
		$filepath = 'my-images/' . 'image_' . $imgAppend;
		$thumbpath = 'my-images/' . 'thumb_' . $imgAppend;
		
		$this->tuxS3Util->setBucket('myalcoholist-tuxin-com');
		$this->tuxS3Util->delete($filepath);
		$this->tuxS3Util->delete($thumbpath);
		$this->deleteImageFromDb($imageId);
	}
	
	public function deleteImage($imageId) {
		$imgAppend=sprintf('%010u',$imageId).'.png';
		$filepath = IMAGES_DIRECTORY . 'image_' . $imgAppend;
		$thumbpath = IMAGES_DIRECTORY . 'thumb_' . $imgAppend;
		unlink($filepath);
		unlink($thumbpath);
		$this->deleteImageFromDb($imageId);
		
	}
	
	private function deleteImageFromDb($imageId) {
		$globalImageTable=  $this->getGlobalImageTable();
		$globalImageTable->delete(array('global_image_id'=>$imageId));
		$globalImageLinkTable = $this->getGlobalImageLinkTable();
		$globalImageLinkTable->delete(array('global_image_id'=>$imageId));
		$surveAttrTypeTable = $this->getSurveAttrTypeTable();
		$surveAttrTypeTable->update(array('global_image_id'=>NULL),array('global_image_id'=>$imageId));
		$shakerTypeTable = $this->getShakerTypeTable();
		$shakerTypeTable->update(array('global_image_id'=>null),array('global_image_id'=>$imageId));
		$glassTypeTable = $this->getGlassTypeTable();
		$glassTypeTable->update(array('global_image_id'=>null),array('global_image_id'=>$imageId));
				
	}
	
	
	
	public function uploadImage($fileData,$previewImageRotation=0, $uploadToS3=false) {
		if ($fileData['error'] == 0) { // image uploaded properly
	
			if (in_array($fileData['type'],$this->supportedImageMimeTypes)) {
	
				$this->tuxS3Util->setBucket('myalcoholist-tuxin-com');
				
				$imageId = $this->getGlobalImageTable()->createEmptyRow();
				$imgAppend=sprintf('%010u',$imageId).'.png';
				$filepath = $this->imagesDirectory . 'image_' . $imgAppend;
				$thumbpath = $this->imagesDirectory . 'thumb_' . $imgAppend;

				$s3filepath = 'my-images/image_' . $imgAppend;
				$s3thumbpath = 'my-images/thumb_' . $imgAppend;
								
				$im = new \Imagick();
				$im->readImage($fileData['tmp_name']);
				$profiles = $im->getImageProfiles("icc", true);
				$im->stripimage();
				if(!empty($profiles)) {
					$im->profileImage("icc", $profiles['icc']);
				}
				if (is_numeric($previewImageRotation) && $previewImageRotation > 0) {
					$im->rotateimage(new \ImagickPixel('#00000000'), $previewImageRotation);
				}
				if (!$uploadToS3) {
				$result=$im->writeImage($filepath);
					
				if (!$result) {
					error_log("uploaded image could not be moved to the appropriate location");
					//		$this->messanger->addErrorMessage('information was added without the image. there was an error uploading the image. try again later');
				}
				} else {
					$result = $im->getimageblob();
                    error_log("s3 path: ".$s3filepath);
					$this->tuxS3Util->uploadPng($s3filepath, $result);
				}
	
				$im->resizeImage(100,100, \Imagick::FILTER_LANCZOS, 0.9, true);
				if (!$uploadToS3) {
				$result=$im->writeImage($thumbpath);
			
				if (!$result) {
					error_log("thumbnail could not be moved to the appropriate location");
					//	$this->messanger->addErrorMessage('information was added without the image. there was an error converting it to a thumbnail. try again later');
	
				}
				} else {
					$result = $im->getimageblob();
					$this->tuxS3Util->uploadPng($s3thumbpath, $result);
				}
				$im->clear();
				$im->destroy();
	
				return $imageId;
			} else {
				error_log('information was added to db without the image, image format not supported');
				//$this->messanger->addMessage('information was added to db without the image, image format not supported');
				return null;
			}
		} else {
			error_log("image failed to upload properly");
			return null;
		}
	}
	
	public function getDrinkImagesPendingData() {
		$globalImageLinkPendingTable = $this->getGlobalImageLinkPendingTable();
		$select = $globalImageLinkPendingTable->newSelect();
		$globalImageLinkPendingTable->getSelect($select,array('global_image_link_pending_imageid','global_image_link_pending_id'))
		->join('drink_flavor', 'drink_flavor.drink_flavor_id = global_image_link_pending.global_image_link_pending_pkey',array(),'left')
		->join('drink_flavor_type','drink_flavor.drink_flavor_type_id=drink_flavor_type.drink_flavor_type_id',array('drink_flavor_type_name'),'left')
		->join('drink','drink.drink_id = drink_flavor.drink_id',array(),'left')
		->join('drink_brand','drink_brand.drink_brand_id  = drink.drink_brand_id',array('drink_brand_name'),'left')
		->join('drink_type','drink_type.drink_type_id = drink.drink_type_id',array('drink_type_name'),'left')
		->join('drink_company','drink_company.drink_company_id = drink_brand.drink_company_id',array('drink_company_name'),'left')
		->where(array('global_image_link_pending_typeid'=>1));
		$resultSet = $globalImageLinkPendingTable->selectWith($select);
		if ($resultSet->count() > 0) {
			return $resultSet->toArray();
		} else {
			return null;
		}
	}

	public function updateGlassTypeImage($glassTypeId,$fileData) {
		$imageId=$this->uploadImage($fileData,0,true);
		if ($imageId != null) {
			$glassTypeTable = $this->getGlassTypeTable();
			$glassTypeTable->update(array('global_image_id'=>$imageId),array('glass_type_id'=>$glassTypeId));
		}
		return $imageId;
	}
	
	public function updateShakerTypeImage($shakerTypeId,$fileData) {
		$imageId=$this->uploadImage($fileData,0,true);
		if ($imageId != null) {
			$shakerTypeTable = $this->getShakerTypeTable();
			$shakerTypeTable->update(array('global_image_id'=>$imageId),array('shaker_type_id'=>$shakerTypeId));
		}
		return $imageId;
	}
	
	
	
	public function updateSurveAttrTypeImage($surveAttrTypeId,$fileData) {
		$imageId=$this->uploadImage($fileData,0,true);
		if ($imageId != null) {
			$surveAttrTypeTable = $this->getSurveAttrTypeTable();
			$surveAttrTypeTable->update(array('global_image_id'=>$imageId),array('surve_attr_type_id'=>$surveAttrTypeId));
		}
		return $imageId;
		
	}
	
	public function getImagesAndRelationsCount() {
	
		$globalImageTable=$this->getGlobalImageTable();
		$select = $globalImageTable->newSelect();
		$globalImageTable->getSelect($select,array('global_image_id',
				'link_drink_count'=>new Expression('sum(case when global_image_link.global_image_type_id = 1 then 1 else 0 end)'),
				'link_cocktail_count'=>new Expression('sum(case when global_image_link.global_image_type_id = 2 then 1 else 0 end)'),
				'link_glass_type_count'=>new Expression('sum(case when global_image_link.global_image_type_id = 3 then 1 else 0 end)'),
				'link_pending_count'=>new Expression('count(global_image_link_pending.global_image_link_pending_id)'),
				'glass_type_count'=>new Expression('count(distinct glass_type.global_image_id)'),
				'shaker_type_count'=>new Expression('count(distinct shaker_type.global_image_id)'),
				'addin_type_count'=>new Expression('count(distinct surve_attr_type.global_image_id)')))
				->join('global_image_link','global_image_link.global_image_id = global_image.global_image_id',array(),'left')
				->join('global_image_link_pending','global_image_link_pending.global_image_link_pending_imageid = global_image.global_image_id',array(),'left')
				->join('glass_type', 'glass_type.global_image_id=global_image.global_image_id',array(),'left')
				->join('shaker_type','shaker_type.global_image_id=global_image.global_image_id',array(),'left')
				->join('surve_attr_type','surve_attr_type.global_image_id=global_image.global_image_id',array(),'left')
				->group('global_image.global_image_id');
		$resultSet = $globalImageTable->selectWith($select);
		if ($resultSet->count() == 0) {
			return null;
		}
		return $resultSet->toArray();
	}
	
}

